﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using CardGenerator.Annotations;
using CardGenerator.UI.Pages;
using PropertyChanged;

namespace CardGenerator.ViewModel;

[AddINotifyPropertyChangedInterface]
public class TemplateManagerViewModel
{
    public ObservableCollection<CardTemplate> Templates { get; private set; } = new();
    public CardTemplate? SelectedTemplate { get; set; }
    public Boolean IsReady { get; private set; } = false;
    public ICommand CreateTemplateCommand { get; private set; }
    public ICommand DeleteTemplateCommand { get; private set; }
    public ICommand SaveTemplatesCommand { get; private set; }
    public ICommand ImportTemplateFileCommand { get; private set; }
    public ICommand ExportTemplateFileCommand { get; private set; }

    public TemplateManagerViewModel()
    {
        
    }

    public void Initialize(TemplateManagerPage templateManagerPage)
    {
        var filePath = Path.Combine(Environment.CurrentDirectory, "Templates.json");
        Task.Run(async () =>
        {
            if (!File.Exists(filePath))
            {
                this.SaveTemplatesCommand.Execute(null);
            }

            var jsonText = await File.ReadAllTextAsync(filePath);
            var jsonObject = JsonSerializer.Deserialize<CardTemplate[]>(jsonText);
            Application.Current.Dispatcher.Invoke(() =>
            {
                this.Templates.Clear();
                jsonObject.ToList().ForEach(template => this.Templates.Add(template));
                this.IsReady = true;
            });
        });
        this.createCommands(templateManagerPage);
    }

    private void createCommands(TemplateManagerPage window)
    {
        this.CreateTemplateCommand = new ClickCommand(parameter =>
        {
            this.Templates.Add(new CardTemplate()
            {
                Name = "Unnamed"
            });
            this.SaveTemplatesCommand.Execute(null);
        });
        this.DeleteTemplateCommand = new ClickCommand(parameter =>
        {
            this.Templates.Remove(this.SelectedTemplate);
            this.SaveTemplatesCommand.Execute(null);
            this.SelectedTemplate = null;
        });
        this.SaveTemplatesCommand = new ClickCommand(async parameter =>
        {
            var filePath = Path.Combine(Environment.CurrentDirectory, "Templates.json");
            var jsonText = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(this.Templates.Select(item => item).ToArray()));
            await File.WriteAllTextAsync(filePath, jsonText);
        });
        var createDirectoryIfNotExists = () =>
        {
            var directoryPath = Path.Join(Environment.CurrentDirectory, "Templates");
            if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
        };
        this.ImportTemplateFileCommand = new ClickCommand(async parameter =>
        {
            var fileLocation = window.ShowTemplateSelectionDialog();
            if (fileLocation == null) return;
            createDirectoryIfNotExists();
            File.Copy(fileLocation, SelectedTemplate.GetTemplateFilePath(), true);
            window.ShowMessageBox("导入成功");
        });
        this.ExportTemplateFileCommand = new ClickCommand(async parameter =>
        {
            createDirectoryIfNotExists();
            if (!SelectedTemplate?.IsTemplateFileExists() ?? false)
            {
                window.ShowMessageBox("当前还没有导入模板文件");
                return;
            }
            var newFilePath = window.ShowTemplateSaveDialog(this.SelectedTemplate?.Name);
            if (newFilePath == null) return;
            File.Copy(SelectedTemplate.GetTemplateFilePath(), newFilePath, true);
            window.ShowMessageBox("导出成功");
        });
    }
}

[AddINotifyPropertyChangedInterface]
public class CardTemplate
{
    public String Name { get; set; }
    public String Id { get; set; } = Guid.NewGuid().ToString("D");
    public String GetTemplateFilePath() => Path.Join(Environment.CurrentDirectory, "Templates", Id);
    public Boolean IsTemplateFileExists() => File.Exists(GetTemplateFilePath());
}
